Fork me on GitHub

1114. Print in Order

Easy

Suppose we have a class:

1
2
3
4
5
public class Foo {
public void first() { print("first"); }
public void second() { print("second"); }
public void third() { print("third"); }
}

The same instance of Foo will be passed to three different threads. Thread A will call first(), thread B will call second(), and thread C will call third(). Design a mechanism and modify the program to ensure that second() is executed after first(), and third() is executed after second().

Example 1:

1
2
3
Input: [1,2,3]
Output: "firstsecondthird"
Explanation: There are three threads being fired asynchronously. The input [1,2,3] means thread A calls first(), thread B calls second(), and thread C calls third(). "firstsecondthird" is the correct output.

Example 2:

1
2
3
Input: [1,3,2]
Output: "firstsecondthird"
Explanation: The input [1,3,2] means thread A calls first(), thread B calls third(), and thread C calls second(). "firstsecondthird" is the correct output.

多线程 multithread: different thread share the same storage, may appears the situation that they address the same global variable at the same time, so we don’t know which one is first. and the result may different during different running.

  1. using barrier
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from threading import Barrier
class Foo:
def __init__(self):
self.first_barrier = Barrier(2)
self.second_barrier = Barrier(2)

def first(self, printFirst: 'Callable[[], None]') -> None:
# printFirst() outputs "first". Do not change or remove this line.
printFirst()
self.first_barrier.wait()


def second(self, printSecond: 'Callable[[], None]') -> None:
self.first_barrier.wait()
# printSecond() outputs "second". Do not change or remove this line.
printSecond()
self.second_barrier.wait()


def third(self, printThird: 'Callable[[], None]') -> None:
self.second_barrier.wait()
# printThird() outputs "third". Do not change or remove this line.
printThird()
  1. using locks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from threading import Lock
class Foo:
def __init__(self):
self.locks = (Lock(),Lock())
self.locks[0].acquire()
self.locks[1].acquire()

def first(self, printFirst: 'Callable[[], None]') -> None:
# printFirst() outputs "first". Do not change or remove this line.
printFirst()
self.locks[0].release()

def second(self, printSecond: 'Callable[[], None]') -> None:
with self.locks[0]:
# printSecond() outputs "second". Do not change or remove this line.
printSecond()
self.locks[1].release()

def third(self, printThird: 'Callable[[], None]') -> None:
with self.locks[1]:
# printThird() outputs "third". Do not change or remove this line.
printThird()
Shuolin Tian wechat
欢迎加我微信交流